#pragma once

#include <iostream>
#include <stdarg.h>
#include <time.h>
#include <sys/stat.h>
#include <unistd.h> 
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>


#define SIZE 1024

#define LogFile "log.txt"

#define Info     0
#define Debug    1
#define Warning  2
#define Error    3
#define Fatal    4

#define Screan     1
#define Onefile    2
#define Classfile  3

class Log
{
public:
    Log()
    {
        printMethod = Screan;
    }

    void Enable(int method)
    {
        printMethod = method;
        path = "./log/";
    }

    std::string levelToString(int level)
    {
        switch(level)
        {
            case Info: return "Info";
            case Debug: return "Debug";
            case Warning: return "Warning";
            case Error: return "Error";
            case Fatal: return "Fatal";
            default: return "None";
        }
    }

    // void logmessage(int level,const char* format,...)
    // {
    //     time_t t = time(nullptr);
    //     struct tm* ctime = localtime(&t);
    //     char leftbuffer[SIZE];
    //     snprintf(leftbuffer,sizeof(leftbuffer),"[%s][%d-%d-%d %d:%d:%d]",
    //     levelToString(level).c_str(),ctime->tm_year + 1900,ctime->tm_mon + 1,ctime->tm_mday,
    //     ctime->tm_hour,ctime->tm_min,ctime->tm_sec);

    //     va_list s;
    //     va_start(s,format);
    //     char rightbuffer[SIZE];
    //     vsnprintf(rightbuffer,sizeof(rightbuffer),format,s);
    //     va_end(s);

    //     //格式化：默认部分+自定义部分
    //     char logtxt[2*SIZE];
    //     snprintf(logtxt,sizeof(logtxt),"%s %s",leftbuffer,rightbuffer);

    //     // printf("%s",logtxt); //暂时打印
    //     printLog(level,logtxt);
    // }


    void printLog(int level,std::string logtxt)
    {
        switch(printMethod)
        {
            case Screan:
                std::cout<<logtxt<<std::endl;
            break; 
            case Onefile:
                printOneFile(LogFile,logtxt);
            break; 
            case Classfile:
                printClassFile(level,logtxt);
            break; 
            default:
            break;
        }
    }

    void printOneFile(const std::string &logname, const std::string &logtxt)
    {
        std::string _logname = path + logname;
        int fd = open(_logname.c_str(),O_WRONLY|O_APPEND|O_CREAT,0666);//"log.txt"
        if(fd < 0) return;
        write(fd,logtxt.c_str(),logtxt.size());
        close(fd);
    }

    void printClassFile(int level, const std::string &logtxt)
    {
        std::string filename = LogFile;
        filename += ".";
        filename += levelToString(level);//"log.txt.Debug/Warming/Fatal"
        printOneFile(filename,logtxt);
    }

    void operator()(int level, const char* format,...)
    {
        time_t t = time(nullptr);
        struct tm* ctime = localtime(&t);
        char leftbuffer[SIZE];
        snprintf(leftbuffer,sizeof(leftbuffer),"[%s][%d-%d-%d %d:%d:%d]",
        levelToString(level).c_str(),ctime->tm_year + 1900,ctime->tm_mon + 1,ctime->tm_mday,
        ctime->tm_hour,ctime->tm_min,ctime->tm_sec);

        va_list s;
        va_start(s,format);
        char rightbuffer[SIZE];
        vsnprintf(rightbuffer,sizeof(rightbuffer),format,s);
        va_end(s);

        //格式化：默认部分+自定义部分
        char logtxt[2*SIZE];
        snprintf(logtxt,sizeof(logtxt),"%s %s",leftbuffer,rightbuffer);

        // printf("%s",logtxt); //暂时打印
        printLog(level,logtxt);
    }
       
private:
    int printMethod;
    std::string path;

};
// int sum(int n,...)
// {
//     va_list s; // char*
//     va_start(s,n);

//     int sum = 0;
//     while(n--)
//     {
//         sum += va_arg(s,int);//printf("hello %d,hello %f,hello %s",1,3.14,"hello");
//     }
//     va_end(s); // s = NULL

//     return sum;
// }